向量检索记忆
kNN-LM 到生产 ANN 索引的演进,以及两阶段粗召回 + 精排的 pipeline 设计
核心要点:
- 检索记忆 = 外存解耦 + 推理时取回
- kNN-LM / Memorizing Transformer:学术检索增强
- ANN 索引:Flat / IVF / HNSW / PQ 各有权衡
- 两阶段:ANN 粗召回 + cross-encoder 精排
- hybrid:向量 + BM25 用 RRF 融合
本文讲检索型记忆的机制,从学术原型到生产 pipeline。具体生产系统如何组合见 07-生产记忆系统对标。
检索型记忆的基本思路是什么?
核心问题:模型参数装不下所有知识,怎么在推理时按需取回?
把外部存储与模型推理解耦,推理时按相似度或关键词取回相关片段注入上下文。这条路线让记忆容量不受模型参数和上下文窗口限制,代表工作按时间是 kNN-LM(2020)→ Memorizing Transformer(2022)→ 生产级系统(2023 后)。
两个核心设计决策贯穿全线:记忆存什么形态(token、隐状态、还是 (key,value) 对)和检索在哪一层介入(输出层、中间层、还是 prompt 层)。前两节看学术原型怎么做,后两节看生产系统怎么落地。
kNN-LM 怎么不训练就增强记忆?
核心问题:不改一个权重,能给语言模型外挂记忆吗?
能——kNN-LM 在输出层把模型预测与最近邻检索结果插值[1]。它不训练,只构建一张外部 (key, value) 表。
机制分三步:
- 建库:对语料前向传播,每个位置取最后一层隐状态作 key、下一个 token 作 value,用 FAISS 建近似最近邻索引。
- 检索:推理时用当前隐状态查 $k$ 个最近邻,对相同 next-token 的距离取 softmax,得 $p_\text{kNN}$。
- 插值:最终预测是两者加权:
在 Wikitext-103 上,这一无训练增强把 perplexity 从 18.65 降到 16.12(叠加 Continuous Cache 可进一步到 15.79),对罕见模式和事实知识改善最大。最可借鉴的一点是 域适应无需重训:只换 datastore 就能让同一模型适配新领域。背后的直觉是,学文本相似度比直接预测下一个词更容易,最近邻搜索能覆盖长尾分布。
Memorizing Transformer 比 kNN-LM 强在哪?
核心问题:检索一定要在输出层做吗,能不能让模型学会怎么用记忆?
Memorizing Transformer 把 kNN 检索搬进中间层注意力,并用可学习 gate 融合[2]。这让模型自己学会何时依赖记忆,而非固定线性加权。
两个关键升级:
- 中间层融合:key/value 都是中间层激活(如 12 层取第 6 层)。中间层比输入 embedding 语义更丰富,比最终层受任务分布干扰更少。当前 token 在该层查 $k=32$–$256$ 个最近邻得检索注意力,再经 per-token gate 与本地注意力融合。
- 推理时可写入:不同于 kNN-LM 的静态 datastore,它支持推理时动态写新记忆(无需改权重),模型在测试时即可用上刚定义的函数、定理。验证至 262K token 外部记忆,性能随记忆量线性提升。
二者的本质差异是 输出层插值 vs 中间层学习融合:前者是事后线性加权,后者让模型学习如何整合检索内容。这条"让模型学会用记忆,而非硬加权"的思路,对设计 agent 检索策略有借鉴价值。
ANN 索引怎么选?
核心问题:生产里几百万条记忆,用什么索引既快又准又省内存?
精确检索 O(n) 不可扩展,生产用近似最近邻(ANN);Flat / IVF / HNSW / PQ 在召回率、延迟、内存上各占一角[3][4]。选型本质是三者的三角权衡(下表为工程经验值)。
| 索引 | 内存 | 召回率 | 适用 |
|---|---|---|---|
| Flat(精确) | 1× | 100% | 小规模、要精确 |
| IVF(倒排+聚类) | ~1.1× | 调 nprobe 可控 | 50M+ 静态数据 |
| HNSW(分层图) | 2-5× | 开箱 95%+ | <10M 动态数据,默认首选 |
| IVF-PQ(乘积量化) | ~4%(压 64×) | 50-90% | 内存吃紧的超大规模 |
@tbl-agent-memory-ann-index-comparison ANN 索引四种类型对比:Flat、IVF、HNSW、IVF-PQ 的内存开销、召回率与适用场景
陷阱:HNSW 在强过滤场景(>90% 数据被过滤掉)会严重退化,此时应转 IVF。 例子:PQ 把 1M 向量压到约 9.2MB、单查询约 0.09ms(工程实测),代价是召回率下降——用召回率换内存[4]。
可借鉴的默认:动态、规模 <10M → HNSW;静态超大规模 → IVF 或 IVF-PQ。记忆系统的写入频繁,多偏 HNSW。
HNSW 实测:M / efSearch / 规模如何换召回与延迟?
核心问题:HNSW 是 ANN 默认首选,但 M 和 efSearch 该怎么调,规模上去之后会怎么塌?
召回从 0.90 推到 0.95 的代价远高于从 0.72 推到 0.90;规模与过滤选择度是两条独立退化轴[5][6][7]。三块数据给出量化骨架。
efSearch 对召回-延迟的边际曲线
固定 M=16,单节点部署,efSearch 从 40 推到 640[5]:
| efSearch | Recall@10 | 平均延迟 |
|---|---|---|
| 40 | 0.72 | 11.5 ms |
| 240 | 0.90 | 35.0 ms |
| 640 | 0.95 | 68.3 ms |
@tbl-agent-memory-hnsw-efsearch HNSW 的 efSearch 对召回率与查询延迟的影响:固定 M=16 时三组测量数据
0.72 → 0.90 大约 efSearch ×6,延迟 ×3;0.90 → 0.95 efSearch 再 ×2.7,延迟翻倍。曲线在 0.95 以上更陡,实际项目要 0.99 召回时延迟可能再翻几倍——所以"追极致召回"在 HNSW 上代价不对称,必要时考虑两阶段检索 (粗召回不必追 0.99) 或换索引。
内存开销公式
hnswlib / OpenSearch 文档给出的估算[8][9]:
$$\begin{equation} \text{bytes per vector} \approx 1.1 \times (4 \cdot \text{dim} + 8 \cdot M) \label{eq:mem-hnsw-mem} \end{equation}$$以 dim=1536(OpenAI embedding), M=16 为例:$1.1 \times (6144 + 128) \approx 6\,900$ bytes/向量,图结构相对向量本体约 +12%。高维场景下 M 对总内存的边际影响小(向量本体是大头);低维 (dim=128) 场景 M 才显著影响总内存。这条经验对存"短句 embedding"和"长文档 chunk embedding"的容量规划意味不同。
Weaviate 公开 ANN benchmark 的工程基准
跨规模和向量维度的实测数据[6]:
| 数据集 | 规模 | dim | M / efSearch | Recall@10 | p99 延迟 |
|---|---|---|---|---|---|
| SIFT1M | 1M | 128 | 32 / 64 | 98.35% | 3.13 ms |
| DBPedia-OpenAI | 1M | 1536 | 16 / 96 | 97.24% | 4.43 ms |
| Sphere DPR | 10M | 768 | 32 / 96 | 96.06% | 7.73 ms |
@tbl-agent-memory-hnsw-weaviate-bench Weaviate 公开 ANN benchmark 跨数据集工程基准:规模、维度、参数与召回率、p99 延迟
可借鉴:1M 规模 p99 在 3–5ms, 10M 推到 7–8ms 仍守得住 96% 召回——但 Sphere DPR 用了 ACORN 过滤机制和较高 efConstruction=384,不是裸 HNSW。裸 HNSW 在 10M 上要么牺牲召回,要么延迟膨胀。
规模与过滤两条退化轴
规模轴:同样参数下,库从 50K 长到 200K, recall@5 从 ~0.78 掉到 ~0.68 (Wikipedia 数据集)[7]。"100K 调好的 efSearch,到 1M 就不够"是工程经验。意味着 efSearch 不是一次设定终身适用,库增长时要重新调。
过滤轴:强过滤 (selectivity < 10%) 场景下,post-filter 方式可能要扫 10× k 个候选才能凑满 k 个命中,延迟从 <10 ms 飙到 200–300 ms[10]。Qdrant 的 filterable HNSW、Weaviate 的 ACORN 把过滤集成进图搜索可压回 1.2–1.5× 的开销,召回接近 100%——选 vector store 时有没有 integrated filter 是强过滤场景的关键参数。
什么时候必须换 IVF / IVF-PQ
文献里没有精确"超过 X M 必须换"的阈值,但工程上的判据是:
- 规模超出可全图载入内存(数十 M 向量以上,视 dim 与硬件) → 必须考虑 IVF-PQ。
- 过滤选择度长期 < 5% 且 vector store 无 integrated filter → IVF 倒排 + nprobe 调参更线性。
- 同 90% 召回时 QPS 差距:Faiss 10M 基准下 HNSW 约 3K QPS,多级 IVF-PQ 可达 30–40K QPS[10]——批量服务或高 QPS 场景,IVF-PQ 的吞吐优势会显现。
可借鉴的默认升级路径:HNSW (起步) → integrated-filter HNSW (强过滤进来) → IVF-PQ (容量与吞吐都顶不住时),不一步跳到 IVF-PQ。
为什么要两阶段检索?
核心问题:ANN 一把召回 top-K 直接喂模型,不够吗?
不够——ANN 召回快但粗,要再叠一层 cross-encoder 精排,才能把最相关的顶上来。这就是"粗召回 + 精排"的两阶段漏斗。
| 阶段 | 模型 | 特点 |
|---|---|---|
| 粗召回 | bi-encoder(双塔) | query 和 doc 独立编码,可预计算,O(1) 在线查询,快但精度有限 |
| 精排 | cross-encoder(交互式) | query-doc 拼接做全 attention,精度高但无法预计算,慢 |
@tbl-agent-memory-two-stage-retrieval 两阶段检索对比:bi-encoder 粗召回与 cross-encoder 精排的特点及适用场景
典型漏斗:ANN 召回 top-100 → cross-encoder 精排 top-20 → LLM 用 top-5。精排必须限制候选数——cross-encoder 在 30 QPS 下 p50 延迟可达数秒,候选一多就拖垮延迟。
评估各阶段用不同指标:Recall@k 测召回阶段有没有把相关项捞进来(目标 ≥0.95)、MRR 测精排把第一个相关结果排到第几位、nDCG@k 用对数折扣综合衡量端到端排名质量(MTEB 主指标)。可借鉴的判断:召回阶段追 recall,精排阶段追 precision,两者分工不要用一个指标考核。
embedding 和关键词检索怎么用 RRF 融合?
核心问题:语义检索更先进,为什么生产系统还在用 BM25,又怎么把两者合起来?
两者各有盲区,生产系统用 Reciprocal Rank Fusion(RRF)把向量分和 BM25 分按排名融合。embedding 擅长语义但会平滑长尾稀有词;BM25 靠 IDF 强调稀有词,精确但召回窄。
| 维度 | embedding 检索 | BM25 / 关键词 |
|---|---|---|
| 召回类型 | 语义相似(近义、释义、跨语言) | 精确词汇匹配 |
| 长尾稀有词 | 易被稠密向量平滑 | IDF 天然强调 |
| 更新成本 | 新文档需重 embed | 倒排索引 O(1) 增量 |
| 误召回 | 高相似但不相关的 false positive | 词不匹配则不召回 |
@tbl-agent-memory-embedding-vs-bm25 embedding 语义检索与 BM25 关键词检索的四维对比:召回类型、长尾词、更新成本、误召回特点
RRF 用排名而非原始分数融合,规避了向量分(余弦)和 BM25 分量纲不同的问题[11]:
$$\begin{equation} \text{score}(d) = \sum_{i} \frac{1}{k + \text{rank}_i(d)} \label{eq:mem-rrf} \end{equation}$$其中 $\text{rank}_i(d)$ 是文档 $d$ 在第 $i$ 路检索结果里的排名,$k$ 默认 60。实测在 WANDS 基准上 RRF 融合 nDCG 0.7068,优于 BM25 单独 0.6983 和向量单独 0.6953。Elasticsearch、Weaviate、Qdrant 都原生支持。可借鉴的判断:别在 embedding 和关键词之间二选一,用 RRF 按排名融合,稀有词和语义都不丢。
chunk 切多大?
核心问题:文档切成多大的块去检索,精度最高?
chunk 粒度是精度与上下文完整性的权衡:小则精度高但丢上下文,大则上下文全但引噪声[12]。没有万能尺寸,要按文本结构选策略。
- 固定长度:按 token 数(128–1024)切,加 10–20% 滑窗 overlap。最简单,适合同质文本。
- 句/段落切分:在自然边界切,保语义完整,适合有段落结构的文本。
- 递归字符切分:依次按段落→句→词边界尝试,兼顾结构与长度。
- 语义切分:用 embedding 相似度检测话题转换点切,块更自洽但计算贵。
- Contextual chunking:存储时用 LLM 给每个 chunk 加全局位置前缀再 embed,不扩大块也能提精度。
- 检索后扩展:命中 chunk 后额外返回前后相邻块,兼顾精确命中与充足上下文。
可借鉴的默认起点:递归字符切分 + 检索后扩展,在不引入语义切分计算成本的前提下兼顾结构与上下文。
Takeaway
| 知识点 | 核心结论 |
|---|---|
| 基本思路 | 外存与推理解耦,推理时按相似度取回 |
| kNN-LM | 输出层插值,零训练,换 datastore 即换域 |
| Memorizing Transformer | 中间层 gate 融合 + 推理时可写入,让模型学会用记忆 |
| ANN 索引 | Flat(精确)/ IVF(超大静态)/ HNSW(动态默认)/ PQ(省内存),三角权衡 |
| HNSW 调参 | efSearch 推 0.95 召回延迟翻倍,>0.95 更陡;M 高维下对内存边际小 |
| 退化轴 | 规模(50K→200K recall 掉 10pp)+ 强过滤(<10% selectivity 延迟 20×) |
| 升级路径 | HNSW → integrated-filter HNSW → IVF-PQ,不一步跳 |
| 两阶段检索 | ANN 粗召回 top-100 → cross-encoder 精排 → LLM top-5 |
| RRF 融合 | 按排名融合向量与 BM25,k=60,规避量纲问题 |
| 评估指标 | 召回追 Recall@k,精排追 MRR/nDCG |
| chunk 策略 | 默认递归切分 + 检索后扩展 |
参考资料
- Khandelwal et al. Generalization through Memorization: Nearest Neighbor Language Models. ICLR 2020. arXiv:1911.00172. https://arxiv.org/abs/1911.00172
- Wu et al. Memorizing Transformers. ICLR 2022 Spotlight. arXiv:2203.08913. https://arxiv.org/abs/2203.08913
- Malkov & Yashunin. Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs. arXiv:1603.09320, 2016. https://arxiv.org/abs/1603.09320
- Pinecone. Product Quantization / Nearest Neighbor Indexes (IVF, HNSW, PQ). 工程基准与内存/召回权衡经验值。https://www.pinecone.io/learn/series/faiss/product-quantization/
- OpenSourceConnections. Vector Search: Navigating Recall and Performance. 2025-02. https://opensourceconnections.com/blog/2025/02/27/vector-search-navigating-recall-and-performance/
- Weaviate Docs. ANN Benchmarks (DBPedia OpenAI / SIFT1M / Sphere DPR). https://docs.weaviate.io/weaviate/benchmarks/ann
- Towards Data Science. HNSW at Scale: Why your RAG system gets worse as the vector database grows. 2024. https://towardsdatascience.com/hnsw-at-scale-why-your-rag-system-gets-worse-as-the-vector-database-grows/
- hnswlib. ALGO_PARAMS.md. https://github.com/nmslib/hnswlib/blob/master/ALGO_PARAMS.md
- OpenSearch Docs. k-NN Index Memory Estimation. https://opensearch.org/docs/1.2/search-plugins/knn/knn-index/
- Yudhiesh. The Achilles Heel of Vector Search: Filters. 2025-05. https://yudhiesh.github.io/2025/05/09/the-achilles-heel-of-vector-search-filters/
- Cormack, Clarke & Buettcher. Reciprocal Rank Fusion outperforms Condorcet and individual rank learning methods. SIGIR 2009. https://dl.acm.org/doi/10.1145/1571941.1572114
- Pinecone. Chunking Strategies for LLM Applications. 2024. https://www.pinecone.io/learn/chunking-strategies/
延伸阅读
- 04-文件型外置记忆 — 与向量检索并行的另一条记忆路径
- 07-生产记忆系统对标 — 这些机制如何组合成生产系统